/*     */ package com.zimbra.cs.service.mail;
/*     */ 
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.mailbox.CalendarItem;
/*     */ import com.zimbra.cs.mailbox.Folder;
/*     */ import com.zimbra.cs.mailbox.MailServiceException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxLock;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mailbox.calendar.Invite;
/*     */ import com.zimbra.cs.mailbox.calendar.InviteChanges;
/*     */ import com.zimbra.cs.mailbox.calendar.RecurId;
/*     */ import com.zimbra.cs.mailbox.calendar.ZAttendee;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.service.util.ItemIdFormatter;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.util.ArrayList;
/*     */ import java.util.HashSet;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import javax.mail.Address;
/*     */ import javax.mail.Message.RecipientType;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.internet.InternetAddress;
/*     */ import javax.mail.internet.MimeMessage;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class ModifyCalendarItem
/*     */   extends CalendarRequest
/*     */ {
/*     */   protected class ModifyCalendarItemParser
/*     */     extends ParseMimeMessage.InviteParser
/*     */   {
/*     */     private Invite mInv;
/*     */     private Invite mSeriesInv;
/*     */     private List<ZAttendee> mAttendeesAdded;
/*     */     private List<ZAttendee> mAttendeesCanceled;
/*     */     
/*     */     ModifyCalendarItemParser(Invite inv, Invite seriesInv)
/*     */     {
/*  60 */       this.mInv = inv;
/*  61 */       this.mSeriesInv = seriesInv;
/*  62 */       this.mAttendeesAdded = new ArrayList();
/*  63 */       this.mAttendeesCanceled = new ArrayList();
/*     */     }
/*     */     
/*  66 */     public List<ZAttendee> getAttendeesAdded() { return this.mAttendeesAdded; }
/*  67 */     public List<ZAttendee> getAttendeesCanceled() { return this.mAttendeesCanceled; }
/*     */     
/*     */     public ParseMimeMessage.InviteParserResult parseInviteElement(ZimbraSoapContext lc, OperationContext octxt, Account account, Element inviteElem)
/*     */       throws ServiceException
/*     */     {
/*  72 */       ParseMimeMessage.InviteParserResult toRet = CalendarUtils.parseInviteForModify(account, ModifyCalendarItem.this.getItemType(), inviteElem, this.mInv, this.mSeriesInv, this.mAttendeesAdded, this.mAttendeesCanceled, !this.mInv.hasRecurId());
/*     */       
/*  74 */       return toRet;
/*     */     }
/*     */   }
/*     */   
/*     */   public Element handle(Element request, Map<String, Object> context) throws ServiceException
/*     */   {
/*  80 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  81 */     Account acct = getRequestedAccount(zsc);
/*  82 */     Mailbox mbox = getRequestedMailbox(zsc);
/*  83 */     OperationContext octxt = getOperationContext(zsc, context);
/*     */     
/*     */ 
/*     */ 
/*  87 */     Element msgElem = request.getElement("m");
/*  88 */     String folderStr = msgElem.getAttribute("l", null);
/*  89 */     ItemId iid = new ItemId(request.getAttribute("id"), zsc);
/*  90 */     if (!iid.belongsTo(acct))
/*     */     {
/*  92 */       if (folderStr != null)
/*     */       {
/*  94 */         ItemId folderFQ = new ItemId(folderStr, zsc);
/*  95 */         msgElem.addAttribute("l", folderFQ.toString());
/*     */       }
/*  97 */       return proxyRequest(request, context, iid.getAccountId());
/*     */     }
/*     */     
/*     */ 
/* 101 */     boolean isInterMboxMove = false;
/* 102 */     ItemId iidFolder = null;
/* 103 */     if (folderStr != null) {
/* 104 */       iidFolder = new ItemId(folderStr, zsc);
/* 105 */       isInterMboxMove = !iidFolder.belongsTo(mbox);
/*     */     }
/*     */     
/* 108 */     CalendarRequest.MailSendQueue sendQueue = new CalendarRequest.MailSendQueue();
/* 109 */     Element response = getResponseElement(zsc);
/* 110 */     int compNum = (int)request.getAttributeLong("comp", 0L);
/* 111 */     mbox.lock.lock();
/*     */     try {
/* 113 */       CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
/* 114 */       if (calItem == null) {
/* 115 */         throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Could not find calendar item");
/*     */       }
/*     */       
/*     */ 
/* 119 */       if (calItem.inTrash()) {
/* 120 */         throw ServiceException.INVALID_REQUEST("cannot modify a calendar item under trash", null);
/*     */       }
/* 122 */       if ((!isInterMboxMove) && (iidFolder != null) && 
/* 123 */         (iidFolder.getId() != calItem.getFolderId())) {
/* 124 */         Folder destFolder = mbox.getFolderById(octxt, iidFolder.getId());
/* 125 */         if (destFolder.inTrash()) {
/* 126 */           throw ServiceException.INVALID_REQUEST("cannot combine with a move to trash", null);
/*     */         }
/*     */       }
/*     */       
/*     */ 
/*     */ 
/* 132 */       int modSeq = (int)request.getAttributeLong("ms", 0L);
/* 133 */       int revision = (int)request.getAttributeLong("rev", 0L);
/* 134 */       if ((modSeq != 0) && (revision != 0) && ((modSeq < calItem.getModifiedSequence()) || (revision < calItem.getSavedSequence())))
/*     */       {
/* 136 */         throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
/*     */       }
/*     */       
/* 139 */       Invite inv = calItem.getInvite(iid.getSubpartId(), compNum);
/* 140 */       if (inv == null) {
/* 141 */         throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
/*     */       }
/* 143 */       Invite seriesInv = calItem.getDefaultInviteOrNull();
/* 144 */       int folderId = calItem.getFolderId();
/* 145 */       if ((!isInterMboxMove) && (iidFolder != null)) {
/* 146 */         folderId = iidFolder.getId();
/*     */       }
/* 148 */       modifyCalendarItem(zsc, octxt, request, acct, mbox, folderId, calItem, inv, seriesInv, response, isInterMboxMove, sendQueue);
/*     */     }
/*     */     finally {
/* 151 */       mbox.lock.release();
/* 152 */       sendQueue.send();
/*     */     }
/*     */     
/*     */ 
/* 156 */     if (isInterMboxMove) {
/* 157 */       CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
/* 158 */       List<Integer> ids = new ArrayList(1);
/* 159 */       ids.add(Integer.valueOf(calItem.getId()));
/* 160 */       ItemActionHelper.MOVE(octxt, mbox, zsc.getResponseProtocol(), ids, calItem.getType(), null, iidFolder);
/*     */     }
/*     */     
/* 163 */     return response;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private Element modifyCalendarItem(ZimbraSoapContext zsc, OperationContext octxt, Element request, Account acct, Mailbox mbox, int folderId, CalendarItem calItem, Invite inv, Invite seriesInv, Element response, boolean isInterMboxMove, CalendarRequest.MailSendQueue sendQueue)
/*     */     throws ServiceException
/*     */   {
/* 173 */     Element msgElem = request.getElement("m");
/*     */     
/* 175 */     ModifyCalendarItemParser parser = new ModifyCalendarItemParser(inv, seriesInv);
/*     */     
/* 177 */     CalendarRequest.CalSendData dat = handleMsgElement(zsc, octxt, msgElem, acct, mbox, parser);
/* 178 */     dat.mDontNotifyAttendees = isInterMboxMove;
/*     */     
/* 180 */     if (!dat.mInvite.hasRecurId()) {
/* 181 */       ZimbraLog.calendar.info("<ModifyCalendarItem> id=%d, folderId=%d, subject=\"%s\", UID=%s", new Object[] { Integer.valueOf(calItem.getId()), Integer.valueOf(folderId), dat.mInvite.isPublic() ? dat.mInvite.getName() : "(private)", dat.mInvite.getUid() });
/*     */     }
/*     */     else
/*     */     {
/* 185 */       ZimbraLog.calendar.info("<ModifyCalendarItem> id=%d, folderId=%d, subject=\"%s\", UID=%s, recurId=%s", new Object[] { Integer.valueOf(calItem.getId()), Integer.valueOf(folderId), dat.mInvite.isPublic() ? dat.mInvite.getName() : "(private)", dat.mInvite.getUid(), dat.mInvite.getRecurId().getDtZ() });
/*     */     }
/*     */     
/*     */     boolean hasRecipients;
/*     */     try
/*     */     {
/* 191 */       Address[] rcpts = dat.mMm.getAllRecipients();
/* 192 */       hasRecipients = (rcpts != null) && (rcpts.length > 0);
/*     */     } catch (MessagingException e) {
/* 194 */       throw ServiceException.FAILURE("Checking recipients of outgoing msg ", e);
/*     */     }
/*     */     
/* 197 */     if ((!dat.mInvite.isOrganizer()) && (hasRecipients)) {
/* 198 */       throw MailServiceException.MUST_BE_ORGANIZER("ModifyCalendarItem");
/*     */     }
/* 200 */     if (!dat.mInvite.isOrganizer())
/*     */     {
/* 202 */       dat.mInvite.setNeverSent(false);
/* 203 */     } else if (!dat.mInvite.hasOtherAttendees())
/*     */     {
/* 205 */       dat.mInvite.setNeverSent(false);
/* 206 */     } else if (hasRecipients)
/*     */     {
/* 208 */       dat.mInvite.setNeverSent(false);
/*     */     }
/*     */     else {
/* 211 */       assert ((dat.mInvite.hasOtherAttendees()) && (!hasRecipients));
/* 212 */       if (!inv.hasOtherAttendees())
/*     */       {
/*     */ 
/*     */ 
/* 216 */         dat.mInvite.setNeverSent(true);
/*     */       }
/*     */       else
/*     */       {
/* 220 */         dat.mInvite.setNeverSent(inv.isNeverSent());
/*     */       }
/*     */     }
/*     */     
/* 224 */     boolean echo = request.getAttributeBool("echo", false);
/* 225 */     ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
/* 226 */     int maxSize = (int)request.getAttributeLong("max", 0L);
/* 227 */     boolean wantHTML = request.getAttributeBool("html", false);
/* 228 */     boolean neuter = request.getAttributeBool("neuter", true);
/* 229 */     boolean forceSend = request.getAttributeBool("forcesend", true);
/* 230 */     if (inv.isOrganizer())
/*     */     {
/* 232 */       List<ZAttendee> atsCanceled = parser.getAttendeesCanceled();
/* 233 */       if ((!inv.isNeverSent()) && 
/* 234 */         (!atsCanceled.isEmpty())) {
/* 235 */         notifyRemovedAttendees(zsc, octxt, acct, mbox, inv.getCalendarItem(), inv, atsCanceled, sendQueue);
/*     */       }
/*     */       
/*     */ 
/* 239 */       List<ZAttendee> atsAdded = parser.getAttendeesAdded();
/*     */       
/* 241 */       boolean notifyAllAttendees = isNotifyingAll(dat.mMm, atsAdded);
/*     */       
/* 243 */       if (notifyAllAttendees) {
/* 244 */         dat.mInvite.setLastFullSeqNo(dat.mInvite.getSeqNo());
/*     */       } else {
/* 246 */         dat.mInvite.setLastFullSeqNo(inv.getLastFullSeqNo());
/*     */       }
/* 248 */       if (inv.isRecurrence())
/*     */       {
/*     */ 
/* 251 */         removeAllRecipients(dat.mMm);
/*     */         
/*     */ 
/*     */ 
/*     */ 
/* 256 */         if (!acct.isCalendarKeepExceptionsOnSeriesTimeChange()) {
/* 257 */           InviteChanges ic = new InviteChanges(seriesInv, dat.mInvite);
/* 258 */           if (ic.isExceptionRemovingChange()) {
/* 259 */             long now = octxt != null ? octxt.getTimestamp() : System.currentTimeMillis();
/* 260 */             Invite[] invites = calItem.getInvites();
/* 261 */             for (Invite except : invites) {
/* 262 */               if ((!except.isNeverSent()) && (except.hasRecurId()) && (!except.isCancel()) && (inviteIsAfterTime(except, now))) {
/* 263 */                 List<ZAttendee> toNotify = CalendarUtils.getRemovedAttendees(except.getAttendees(), seriesInv.getAttendees(), false, acct);
/*     */                 
/* 265 */                 if (!toNotify.isEmpty()) {
/* 266 */                   notifyRemovedAttendees(zsc, octxt, acct, mbox, calItem, except, toNotify, sendQueue);
/*     */                 }
/*     */               }
/*     */             }
/*     */           }
/*     */         }
/*     */         
/*     */ 
/* 274 */         sendCalendarMessage(zsc, octxt, folderId, acct, mbox, dat, response, true, forceSend, sendQueue);
/*     */         
/*     */ 
/* 277 */         if ((echo) && (dat.mAddInvData != null)) {
/* 278 */           echoAddedInvite(response, ifmt, octxt, mbox, dat.mAddInvData, maxSize, wantHTML, neuter);
/*     */         }
/*     */         
/* 281 */         boolean ignorePastExceptions = true;
/*     */         
/*     */ 
/* 284 */         if ((!atsAdded.isEmpty()) || (!atsCanceled.isEmpty())) {
/* 285 */           addRemoveAttendeesInExceptions(octxt, mbox, inv.getCalendarItem(), atsAdded, atsCanceled, ignorePastExceptions);
/*     */         }
/*     */         
/*     */ 
/* 289 */         if (hasRecipients) {
/* 290 */           notifyCalendarItem(zsc, octxt, acct, mbox, inv.getCalendarItem(), notifyAllAttendees, atsAdded, ignorePastExceptions, sendQueue);
/*     */         }
/*     */         
/*     */       }
/*     */       else
/*     */       {
/* 296 */         sendCalendarMessage(zsc, octxt, folderId, acct, mbox, dat, response, true, forceSend, sendQueue);
/*     */         
/*     */ 
/* 299 */         if ((echo) && (dat.mAddInvData != null)) {
/* 300 */           echoAddedInvite(response, ifmt, octxt, mbox, dat.mAddInvData, maxSize, wantHTML, neuter);
/*     */         }
/*     */       }
/*     */     }
/*     */     else {
/* 305 */       sendCalendarMessage(zsc, octxt, folderId, acct, mbox, dat, response, true, forceSend, sendQueue);
/*     */       
/*     */ 
/* 308 */       if ((echo) && (dat.mAddInvData != null)) {
/* 309 */         echoAddedInvite(response, ifmt, octxt, mbox, dat.mAddInvData, maxSize, wantHTML, neuter);
/*     */       }
/*     */     }
/*     */     
/* 313 */     return response;
/*     */   }
/*     */   
/*     */   private static boolean isNotifyingAll(MimeMessage mm, List<ZAttendee> atsAdded)
/*     */     throws ServiceException
/*     */   {
/* 319 */     Set<String> rcptsSet = new HashSet();
/*     */     try {
/* 321 */       Address[] rcpts = mm.getAllRecipients();
/* 322 */       if (rcpts != null) {
/* 323 */         for (Address rcpt : rcpts) {
/* 324 */           if ((rcpt instanceof InternetAddress)) {
/* 325 */             String email = ((InternetAddress)rcpt).getAddress();
/* 326 */             if (email != null) {
/* 327 */               rcptsSet.add(email.toLowerCase());
/*     */             }
/*     */           }
/*     */         }
/*     */       }
/*     */     } catch (MessagingException e) {
/* 333 */       throw ServiceException.FAILURE("Checking recipients of outgoing msg ", e);
/*     */     }
/*     */     
/* 336 */     for (ZAttendee at : atsAdded) {
/* 337 */       if ((at != null) && (at.getAddress() != null)) {
/* 338 */         rcptsSet.remove(at.getAddress().toLowerCase());
/*     */       }
/*     */     }
/* 341 */     return !rcptsSet.isEmpty();
/*     */   }
/*     */   
/*     */   private static void removeAllRecipients(MimeMessage mm) throws ServiceException {
/*     */     try {
/* 346 */       Message.RecipientType[] rcptTypes = { Message.RecipientType.TO, Message.RecipientType.CC, Message.RecipientType.BCC };
/* 347 */       for (Message.RecipientType rcptType : rcptTypes) {
/* 348 */         mm.setRecipients(rcptType, (Address[])null);
/*     */       }
/*     */     } catch (MessagingException e) {
/* 351 */       throw ServiceException.FAILURE("Checking recipients of outgoing msg ", e);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/ModifyCalendarItem.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */